package com.jweb.framework.ws.client.security;

import java.io.IOException;
import java.security.cert.X509Certificate;
import java.util.Properties;
import java.util.Vector;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.handler.RequestData;
import org.apache.ws.security.handler.WSHandler;
import org.apache.ws.security.message.token.Timestamp;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.security.wss4j.Wss4jSecuritySecurementException;
import org.w3c.dom.Document;

/**
 * 修改人： Thomas  
 * 修改内容：新增 类说明：
 */
public class Wss4jHandlerJWeb extends WSHandler {

	private Properties options;
	private CallbackHandler securementCallbackHandler;
	private String securementPassword;
	private Crypto securementEncryptionCrypto;
	private Crypto securementSignatureCrypto;

	Wss4jHandlerJWeb() {
		options = new Properties();
		options.setProperty("mustUnderstand", Boolean.toString(true));
		options.setProperty("enableSignatureConfirmation", Boolean
				.toString(true));
	}

	protected boolean checkReceiverResults(Vector wsResult, Vector actions) {
		return super.checkReceiverResults(wsResult, actions);
	}

	protected boolean checkReceiverResultsAnyOrder(Vector wsResult,
			Vector actions) {
		return super.checkReceiverResultsAnyOrder(wsResult, actions);
	}

	void setOption(String key, String value) {
		options.setProperty(key, value);
	}

	void setOption(String key, boolean value) {
		options.setProperty(key, Boolean.toString(value));
	}

	public Object getOption(String key) {
		return options.getProperty(key);
	}

	void setSecurementCallbackHandler(CallbackHandler securementCallbackHandler) {
		this.securementCallbackHandler = securementCallbackHandler;
	}

	void setSecurementPassword(String securementPassword) {
		this.securementPassword = securementPassword;
	}

	void setSecurementEncryptionCrypto(Crypto securementEncryptionCrypto) {
		this.securementEncryptionCrypto = securementEncryptionCrypto;
	}

	void setSecurementSignatureCrypto(Crypto securementSignatureCrypto) {
		this.securementSignatureCrypto = securementSignatureCrypto;
	}

	public WSPasswordCallback getPassword(String username, int doAction,
			String clsProp, String refProp, RequestData reqData) {
		WSPasswordCallback callback;
		if (securementCallbackHandler != null) {
			int reason = 0;
			switch (doAction) {
			case 1: // '\001'
			case 64: // '@'
				reason = 2;
				break;

			case 2: // '\002'
				reason = 3;
				break;

			case 4: // '\004'
				reason = 4;
				break;
			}
			callback = new WSPasswordCallback(username, reason);
			Callback callbacks[] = { callback };
			try {
				securementCallbackHandler.handle(callbacks);
			} catch (UnsupportedCallbackException ex) {
				throw new Wss4jSecuritySecurementException(ex.getMessage(), ex);
			} catch (IOException ex) {
				throw new Wss4jSecuritySecurementException(ex.getMessage(), ex);
			}
		} else {
			callback = new WSPasswordCallback(username, 0);
			callback.setPassword(securementPassword);
		}
		return callback;
	}

	public String getPassword(Object msgContext) {
		return securementPassword;
	}

	public Object getProperty(Object msgContext, String key) {
		return ((MessageContext) msgContext).getProperty(key);
	}

	protected Crypto loadEncryptionCrypto(RequestData reqData)
			throws WSSecurityException {
		return securementEncryptionCrypto;
	}

	public Crypto loadSignatureCrypto(RequestData reqData)
			throws WSSecurityException {
		return securementSignatureCrypto;
	}

	public void setPassword(Object msgContext, String password) {
		securementPassword = password;
	}

	public void setProperty(Object msgContext, String key, Object value) {
		((MessageContext) msgContext).setProperty(key, value);
	}

	protected void doSenderAction(int doAction, Document doc,
			RequestData reqData, Vector actions, boolean isRequest)
			throws WSSecurityException {
		super.doSenderAction(doAction, doc, reqData, actions, isRequest);
	}

	protected boolean verifyTimestamp(Timestamp timestamp, int timeToLive)
			throws WSSecurityException {
		return super.verifyTimestamp(timestamp, timeToLive);
	}

	protected boolean verifyTrust(X509Certificate cert, RequestData reqData)
			throws WSSecurityException {
		return super.verifyTrust(cert, reqData);
	}

}
